package com.yimi.appstore.download2;

import java.io.File;
import java.io.FilenameFilter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.os.AsyncTask;
import android.os.Handler;
import android.os.Message;
import android.widget.Toast;

import com.yimi.appstore.YimiApplication;
import com.yimi.appstore.adapter.DownloadJobAdapter;
import com.yimi.appstore.util.GlobalConsts;
import com.yimi.appstore.util.Util;

public class DownloadManager {

	private static final String TAG = "DownloadManager";
	public static final int STATE_DOWNLOADING = 0;
	public static final int STATE_READY_DOWNLOAD = 1;
	public static final int STATE_WAITING = 2;
	public static final int STATE_FINISH = 3;
	public static final int STATE_PAUSE = 4;
	public static final int STATE_PAUSEING = 5;
	public static final int STATE_CANCLE = 6;
	public static final int STATE_REFRESH = 7;
	public static final int STATE_INSTALLED = 8;
	public static final int STATE_ERROR = 8;
	private static DownloadManager sInstance;
	private final int DUPLICATE_BEGIN_INDEX = 2;
	private final Pattern fPattern = Pattern.compile("http://([^/]+/*)+");
	private static Context mContext;
	private Handler mHandler;
	private DownloadJobAdapter downloadJobAdapter;
	private Handler mainHandler;
	/**
	 * 下载任务数
	 */
	private int downloadJobNumber = 1;
	/**
	 * 当前下载任务书
	 */
	private int mDownloadingCount = 0;

	/**
	 * 单例获得实例
	 * 
	 * @param context
	 * @return
	 */
	public synchronized static DownloadManager getInstance(Context context) {
		if (sInstance == null) {
			sInstance = new DownloadManager(context);
		}
		if (mContext == null) {
			mContext = context;
		}
		return sInstance;
	}

	/**
	 * 实例构造函数
	 * 
	 * @param context
	 */
	private DownloadManager(Context context) {
		mHandler = new mHandler();
	}

	public void setMainHanlder(Handler handler) {
		this.mainHandler = handler;
	}

	/**
	 * 刷新下载列表
	 * 
	 * @author Tank
	 * 
	 */
	private class mHandler extends Handler {

		@Override
		public void handleMessage(Message msg) {
			super.handleMessage(msg);
			if (mainHandler == null)
				return;
			switch (msg.what) {
			case STATE_CANCLE:
				if (msg.obj == (Integer) STATE_DOWNLOADING) {
					mDownloadingCount = 0;
					startDownloadTask();
				}
				mainHandler.sendEmptyMessage(0);
				break;
			case STATE_FINISH:
			case STATE_PAUSE:
			case STATE_ERROR:
				mDownloadingCount = 0;
				mainHandler.sendEmptyMessage(0);
				startDownloadTask();
				break;
			case STATE_REFRESH:
			case STATE_PAUSEING:
			case STATE_DOWNLOADING:
			case STATE_READY_DOWNLOAD:
				mainHandler.sendEmptyMessage(0);
				break;
			}
		}

	}

	/**
	 * 添加下载
	 * 
	 * @param url
	 */
	public synchronized void addDownloadTask(String url, String appName, String iconUrl, String mediaType) {
		if (isExitJob(url)) {
			Toast.makeText(mContext, "已经在下载任务中~", Toast.LENGTH_SHORT).show();
			return;
		}
		if (isExitHistoryJob(url)) {
			Toast.makeText(mContext, "已下载此应用~", Toast.LENGTH_SHORT).show();
			return;
		}
		addJobUrl(url);
		Toast.makeText(mContext, "加入下载队列", Toast.LENGTH_SHORT).show();
		new addDownloadTask().execute(url, appName, iconUrl, mediaType);
	}

	class addDownloadTask extends AsyncTask<String, Void, Void> {

		@Override
		protected Void doInBackground(String... params) {
			// TODO Auto-generated method stub
			String fileName = null;
			String localPath = null;
			if (!isUriValid(params[0]))
				return null;
			fileName = parseFileName(params[0]);
			if (Util.isSDCardReady()) {
				localPath = GlobalConsts.APP_SAVESDK_PATH + fileName + ".tmp";
			} else {
				localPath = GlobalConsts.APP_SAVEPHONE_PATH + fileName + ".tmp";
			}
			DownloadEntity downloadEntry = new DownloadEntity(0, params[0], fileName, localPath, -1, 0, params[1],
					params[2], params[3]);
			DownloadJob downloadJob = new DownloadJob(downloadEntry, mContext);
			addJob(downloadJob);
			startDownloadTask();
			DownloadNotify dn = new DownloadNotify(mContext);
			dn.nitify();
			return null;
		}

	}

	public void startDownloadTask() {
		new AsyncTask<Void, Void, Void>() {
			@Override
			protected Void doInBackground(Void... params) {
				for (int i = 0; i < YimiApplication.jobList.size() && mDownloadingCount < downloadJobNumber; i++) {
					if (YimiApplication.jobList.get(i).getJobStatus() == STATE_WAITING) {
						mDownloadingCount++;
						DownloadJob job = YimiApplication.jobList.get(i);
						job.setMhandler(mHandler);
						job.startJob();
					}
				}
				return null;
			}
		}.execute();
	}

	/**
	 * 重新下载
	 * 
	 * @param job
	 */
	public void restartDownloadTask(DownloadJob job, int pos) {
		deleteJob(pos);
		deleteJobUrl(pos);
		addDownloadTask(job.getDownloadEntry().getUrl(), job.getDownloadEntry().getResource(), job.getDownloadEntry()
				.getIconUrl(), job.getDownloadEntry().getMediaType());
	}

	/**
	 * 暂停下载
	 * 
	 * @param url
	 */
	public void pauseDownloadTask(int position) {
		final DownloadJob job = YimiApplication.jobList.get(position);
		if (job != null) {
			new AsyncTask<Void, Void, Void>() {
				@Override
				protected Void doInBackground(Void... params) {
					job.setMhandler(mHandler);
					job.pauseJob();
					return null;
				}

			}.execute();
		}
	}

	/**
	 * 取消下载
	 * 
	 * @param url
	 */
	public void cancleDownloadTask(final int position) {

		final DownloadJob job = YimiApplication.jobList.get(position);
		if (job != null) {
			new AsyncTask<Void, Void, Void>() {

				@Override
				protected void onPreExecute() {
					mainHandler.sendEmptyMessage(1);

				};

				protected Void doInBackground(Void... params) {
					deleteJob(position);
					deleteJobUrl(position);
					job.setMhandler(mHandler);
					job.cancleJob();
					return null;
				}

				protected void onPostExecute(Void result) {
					mainHandler.sendEmptyMessage(2);
				};
			}.execute();

		}
	}

	private boolean isExitJob(String url) {
		for (String downloadUrl : YimiApplication.downloadingList) {
			if (downloadUrl.equals(url))
				return true;
		}
		return false;
	}

	private boolean isExitHistoryJob(String url) {
		for (DownloadEntity de : YimiApplication.downloadHistoryList) {
			if (de.getUrl().equals(url))
				return true;
		}
		return false;
	}

	/**
	 * 根据URI解析获得要下载的文件名
	 * 
	 * @param uriPath
	 * @return
	 */
	private String parseFileName(String uriPath) {
		String result = null;
		int start = uriPath.lastIndexOf('/');
		int end = uriPath.lastIndexOf('?');
		if (end > start)
			result = uriPath.substring(start + 1, end);
		else {
			String temp = uriPath.substring(start + 1);
			if (temp.trim().equals(""))
				result = "index.html";
			else
				result = temp;
		}
		return result;
	}

	/**
	 * 获得合法的文件名
	 * 
	 * @param fileName
	 * @return
	 */
	// private String getValidFileName(String fileName) {
	// char invalidChar[] = { '*', '\\', '|', '"', '\'', '/', '<', '>', '?' };
	// for (char c : invalidChar)
	// fileName = fileName.replace(c, '\0');
	// if (!isStringValid(fileName.trim()))
	// fileName = "index.html";
	// if (!new File(GlobalConsts.APP_PATH, fileName).exists())
	// return fileName;
	// int dot = fileName.lastIndexOf('.');
	// String mainName = null;
	// String suffix = "";
	// if (dot != -1) {
	// suffix = fileName.substring(dot);
	// mainName = fileName.substring(0, dot);
	// } else
	// mainName = fileName;
	// final Pattern p = Pattern.compile("^" + mainName +
	// "\\(([2-9]|([1-9]+\\d*))\\)" + suffix);
	// File dir = new File(GlobalConsts.APP_PATH);
	// String matches[] = dir.list(new FilenameFilter() {
	// @Override
	// public boolean accept(File dir, String filename) {
	// Matcher m = p.matcher(filename);
	// return m.matches();
	// }
	// });
	// ArrayList<Integer> indexs = new ArrayList<Integer>();
	// int count = DUPLICATE_BEGIN_INDEX;
	// for (String m : matches) {
	// int left = m.lastIndexOf('(');
	// int right = m.lastIndexOf(')');
	// indexs.add(Integer.parseInt(m.substring(left + 1, right)));
	// }
	// Collections.sort(indexs);
	// for (Integer i : indexs) {
	// if (i >= DUPLICATE_BEGIN_INDEX && i <= count)
	// count = i + 1;
	// }
	// return mainName + "(" + count + ")" + suffix;
	// }

	/**
	 * 检测字符串是否合法
	 * 
	 * @param string
	 * @return
	 */
	private boolean isStringValid(String string) {
		if (string == null || string.trim().equals(""))
			return false;
		return true;
	}

	/**
	 * 检测URI是否合法
	 * 
	 * @param uriPath
	 * @return
	 */
	private boolean isUriValid(String uriPath) {
		Matcher m = fPattern.matcher(uriPath);
		return m.matches();
	}

	public synchronized void addJob(DownloadJob job) {
		YimiApplication.jobList.add(job);
		mHandler.sendEmptyMessage(STATE_REFRESH);
	}

	public synchronized void addJobUrl(String url) {
		YimiApplication.downloadingList.add(url);
	}

	public synchronized void deleteJob(int pos) {
		if (!YimiApplication.jobList.isEmpty() && YimiApplication.jobList.size() >= pos) {
			YimiApplication.jobList.remove(pos);
		}
	}

	public synchronized void deleteJobUrl(int pos) {
		if (!YimiApplication.downloadingList.isEmpty() && YimiApplication.downloadingList.size() >= pos) {
			YimiApplication.downloadingList.remove(pos);
		}
	}

	public synchronized DownloadJob getJob(int pos) {
		if (!YimiApplication.jobList.isEmpty() && YimiApplication.jobList.size() >= pos) {
			return YimiApplication.jobList.get(pos);
		}
		return null;
	}

	public DownloadJobAdapter getDownloadJobAdapter() {
		return downloadJobAdapter;
	}

	public void setDownloadJobAdapter(DownloadJobAdapter downloadJobAdapter) {
		this.downloadJobAdapter = downloadJobAdapter;
	}

}
